Cutting in Front of the Line

JavaScript 1.2 adds new events which can add greater dimensions to your applet's user interface. They allow you to "cut in line" to handle the events before anything else gets a look at them. They're not as easy to implement as onMouseOver and onMouseOut, though-- so hang onto your mice: it's going to be a bumpy ride!

Events

You already have some idea of what an event is: it's a user action in which you have an interest. Knowing that the user has pressed a button, ticked a checkbox, or moved the mouse cursor over a hotspot is important to your interface. There are more events possible than just these last three, however, and JavaScript 1.2 adds more events to the list, allowing you greater flexibility in designing an interface, and greater programming power overall.

The new events we're going to tackle in the next few recipes are onMouseMove, onMouseDown, and onMouseUp. Before we can get into the main course, though, we need to work our way through a little appetizer first: the new ways that JavaScript 1.2 handles events, and what an Event object looks like.

In order to receive the new events, your applet must register your event handler(s) with the browser. At first, you might think this is not at all like what you did when you handled an onClick event, but it really is: you registered an event-handler function {onClick="MyClickFunc()"} that told the browser you'd like to handle a click event for the given button. The function you registered was for a specific control, whereas the new events are non-specific--they can occur anywhere on the page, not necessarily on, or associated with, a control.

Capturing Events

To register an event handler for the new events, you use the captureEvents() function. The argument to this function represents the events you want your script to handle (join multiple events with the logical OR operator, ( | ). Nothing explains it more clearly than examples:
window.captureEvents(Event.MOUSEMOVE); // Captures movements

window.captureEvents(Event.MOUSEUP | Event.MOUSEDOWN); // Captures button activity

document.captureEvents(Event.CLICK);

document.captureEvents(Event.CLICK | Event.MOUSEMOVE | Event.MOUSEDOWN);
(Yes, you can capture events on either a window- or document-wide basis!) Now that you've told the browser you intend to capture some events, you have to tell it which functions handle the events. To do this, you set a window or document property for the event to the name of the handler function:
window.onMouseMove = MyMoveHandler; // No ()!
Now, of course, it's time to write your event handler!

Event Handlers

An event handler function takes one argument, which is an Event object. The individual properties of the object tell your function what occurred, and where it occurred. Before you can write the function, you need to know what properties are available.

Here are the properties of an Event object. Not all events use all properties; see the individual property recipes to see which uses what. (We've prefixed each property with the name of a fictitious object, evt.)

evt.typeA string representing the event type, i.e. mousemove, mousedown, mouseup.
evt.target A string indicating the object to which the event was originally sent. (If you've captured click events, your handler will see them before the buttons do--even before your onClick handler does!)
evt.layerX A number specifying either the object width when passed with the resize event, or the cursor's horizontal position in pixels relative to the layer in which the event occurred.
evt.layerY A number specifying either the object height when passed with the resize event, or the cursor's vertical position in pixels relative to the layer in which the event occurred.
evt.pageX A number specifying the cursor's horizontal position in pixels, relative to the page.
evt.pageY A number specifying the cursor's vertical position in pixels relative to the page.
evt.screenX A number specifying the cursor's horizontal position in pixels, relative to the screen.
evt.screenY A number specifying the cursor's vertical position in pixels, relative to the screen.
evt.which A number specifying either the mouse button that was pressed or the ASCII value of a pressed key.
evt.modifiers A string specifying the modifier keys associated with a mouse or key event. Modifier key values are: ALT_MASK, CONTROL_MASK, SHIFT_MASK, and META_MASK.
evt.data Returns an array of strings containing the URLs of the dropped objects. Passed with the dragdrop event.

(You've come a long way so far. If you'd like to get up and take a short walk, get a beverage, or do something else to settle your brain, please be our guest!)

Let's look at a short event handler function:

function myEventHandler(evt)
{
    return routeEvent(evt);
}
Two things are obvious--the handler function returns a value, and there's something called "routeEvent" available now. First things first: event handlers return a result of either true or false. The browser uses the return value when handling link click events. When you return true, the browser makes follows the link, and no other event handlers (should there be any) are called. When you return false, the browser ignores the click and cancels any further handling of the event.

That brings us to routeEvent(). This function tries to pass the event on to any other handlers for that event (for example, a button control), and returns whatever the other handler would have returned. You can, as the example shows, pass the return from that handler back straightaway. (The example is, as you can see, sort of a "do-nothing, pass-the-buck" kind of function.)

Finally, you can pass the event directly on to a specific event handler, bypassing the usual chain of command, by calling handleEvent() for the object in question:

function aClickHandler(evt)
{
    return document.forms[0].goButton.handleEvent(evt);
}
This handler routes all click events to the control named goButton on the first form in the document.

Summary

It's been a long haul from the start of this discussion, and your head is probably spinning from the amount of information we've been trying to cram into your brain. The good news is that the recipes that follow are a lot easier to understand than all this (admittedly dry) text! The best thing to do at this point is to look at the first event-handling recipe, Wandering All Over.


Copyright ©2000 by Charles River Media, All Rights Reserved